package com.lwq.fast.log.fastlogserver.task;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.lwq.fast.log.fastlogserver.es.service.ElasticSearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 定时删除文档任务
 */
@Component
@Slf4j
public class DeleteTask {

    /**
     * 默认删除多少天之前的数据
     */
    private final Integer DEFAULT_DAYS_AGO = 7;

    /**
     * 删除多少天之前的数据
     */
    @Value("${delete.days.ago}")
    private Integer daysAgo;

    @Autowired
    private ElasticSearchService elasticSearchService;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 每天凌晨1点删除索引文档
     */
    @Scheduled(cron = "0 0 1 * * ?")
    //@Scheduled(cron = "0/5 * * * * ?")
    public void deleteTask(){

        try{
            List<String> indexList = getAllIndex();
            if (CollectionUtil.isEmpty(indexList)){
                return;
            }

            if (ObjectUtil.isNull(daysAgo)){
                daysAgo = DEFAULT_DAYS_AGO;
            }
            Date dateTime = DateUtils.addDays(new Date(), -daysAgo);

            DeleteByQueryRequest request = new DeleteByQueryRequest(ArrayUtil.toArray(indexList, String.class));
            request.setConflicts("proceed");
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("dateTime")
                    .lte(dateTime);
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(rangeQueryBuilder);
            request.setQuery(boolQueryBuilder);
            request.setRefresh(true);
            BulkByScrollResponse bulkByScrollResponse = restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
            log.info("删除结果={}", JSON.toJSONString(bulkByScrollResponse));
        }catch (Exception e){
            log.error("定时任务删除文档出错",e);
        }


    }

    /**
     * 获取所有的索引信息
     *
     * @throws IOException
     */
    private List<String> getAllIndex() throws IOException {
        List<String> allAppNames = elasticSearchService.getAllAppNames();
        List<String> indices = elasticSearchService.getAllIndices();

        if (CollectionUtil.isEmpty(allAppNames) || CollectionUtil.isEmpty(indices)){
           return Collections.EMPTY_LIST;
        }
        Set<String> appNameSet = allAppNames.stream().collect(Collectors.toSet());
        return indices.stream().filter(entity -> appNameSet.contains(entity)).collect(Collectors.toList());
    }
}
